package com.atguigu.tingshu.common.config.date;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;



@Configuration
public class CustomerDateTimeSerializer {

    /**
     * 自定义ObjectMapper你完成时间（Date）序列化和反序列化
     *
     * @return
     */
    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {

        // 1.创建ObjectMapper对象(直接new 一个新的ObjectMapper 导致默认的其它序列化和反序列化器失效)
//        ObjectMapper objectMapper = new ObjectMapper();
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();  // 用springboot默认的ObjectMapper 不要自己new

        // 2.创建时间模版
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // 3.用时间模板注册序列化器（Date类型的序列化器）
        javaTimeModule.addSerializer(Date.class, new DateSerializer() {
            // 自己完成序列日期的续期

            /**
             * Date:要序列化的人
             * JsonGenerator：序列化工具生成器
             * @param value Value to serialize; can <b>not</b> be null.
             * @param g Generator used to output resulting Json content
             * @param provider Provider that can be used to get serializers for
             *   serializing Objects value contains, if any.
             * @throws IOException
             */
            @Override
            public void serialize(Date value, JsonGenerator g, SerializerProvider provider) throws IOException {
                // 创建SipleDateFormat对象
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                String format = simpleDateFormat.format(value);
                g.writeString(format);
            }
        });
        // 4.用时间模板注册反序列化器（Date类型的反序列化器）
        javaTimeModule.addDeserializer(Date.class, new DateDeserializers.DateDeserializer() {
            /**
             * JsonParser:用于读取JSON内容的解析器
             * @param p Parsed used for reading JSON content
             * @param ctxt Context that can be used to access information about
             *   this deserialization activity.
             *
             * @return
             * @throws IOException
             */
            @Override
            public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {

                // 日期类型的字符串(你自己的时间字符串内容)
                String text = p.getText();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                try {
                    Date date = simpleDateFormat.parse(text);
                    return date;
                } catch (ParseException e) {
                    System.out.println("反序列时间字符串为Date类型对象失败原因：" + e.getMessage());
                    throw new RuntimeException(e);
                }
            }
        });
        // 5.将时间模版放到ObjectMapper中
        objectMapper.registerModule(javaTimeModule);

        // 6.返回
        return objectMapper;
    }


}
